/*
 *    This file is part of CeluMap.
 *
 *    CeluMap is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    CeluMap is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Copyright 2006, 2007, 2008 Gonzalo Merayo
 *    gonzalo (at) celumap.com.ar
 *    www.celumap.com.ar
 *
 */

package map;

import figures.Figure;
import figures.FigureIterator;
import geometry.Rectangle;

public class MemMap implements Map, FigureIterator {
	
	ListNode figs = null;
	ListNode last = null;
	
	Figure f = null;
	Rectangle figsArea = null;
	Rectangle searchArea = null;
	ListNode ifigs = null;
	byte n = 0;
	//Iterator i = null;
	
	public MemMap(int nelems) {
		//figs = new Figure[nelems];
	}
	
	public MemMap() {
	}
	
	public void cacheMap(Map m){
		FigureIterator figs = m.getFigures(null);
		while(figs.hasNext())
			appendFigure(figs.next());
	}

	public FigureIterator getFigures(Rectangle a) {
		searchArea=a;
		ifigs = figs;
		n = 0;
		advance();
		return this;
	}

	public void appendFigure(Figure f) {
		if(figs == null)
			figs = last = new ListNode();
		else if(last.f[ListNode.LENGTH-1]!=null)//last is full
			last = last.n = new ListNode();
		int i=0;
		while(last.f[i]!=null)
			i++;
		last.f[i] = f;
		if(i==0){
			Rectangle r = f.getBoundingBox();
			last.bbxi = r.bbxi;
			last.bbyi = r.bbyi;
			last.bbxf = r.bbxf;
			last.bbyf = r.bbyf;
		}else
			last.unite(f.getBoundingBox());
			
	}

	public boolean hasNext() {
		return f != null;
	}

	public Figure next() {
		Figure ff = f;
		advance();
		return ff;
	}

	private final void advance() {
		f = null;
		if(searchArea==null){
			while(ifigs!=null){
				if(n<ListNode.LENGTH){
					f = ifigs.f[n++];
					return;
				}else{
					ifigs = ifigs.n;
					n = 0;
				}
			}
		}else{
			while(ifigs!=null){
				while(n<ListNode.LENGTH){
					f = ifigs.f[n++];
					if(f==null || searchArea.colides(f.getBoundingBox()))
						return;
				}
				do{
					ifigs = ifigs.n;
					if(ifigs==null)
						return;
				}while(!searchArea.colides(ifigs));
				n = 0;
			}
		}
	}
	///Como veran en este momento no quiero pensar...
	public void removeFigure(Figure selectedFigure) {
		MemMap m = new MemMap();
		FigureIterator it = getFigures(null);
		while(it.hasNext()){
			Figure f = it.next();
			if(f!=selectedFigure)
				m.appendFigure(f);
		}
		figs = m.figs;
		last = m.last;
	}

	public boolean isEmpty() {
		return figs == null;
	}
}
